#include <stdio.h>
#include <stdlib.h>

#define STACK_INIT_SIZE 10
#define STACKINCREMENT 3

typedef struct SqStack
{
    int *base;
    int *top;
    int stack_size;
} SqStack;

bool InitStack(SqStack &S);     // 初始化
bool DestoryStack(SqStack &S);  // 销毁
bool ClearStack(SqStack &S);    // 清空
bool StackEmpty(SqStack S);     // 判空
int StackLength(SqStack S);     // 长度
bool GetTop(SqStack S, int &e); // 栈顶
bool Push(SqStack &S, int e);   // 压栈
bool Pop(SqStack &S, int &e);   // 出栈
void Print(SqStack S);          // 打印

// 初始化
bool InitStack(SqStack &S)
{
    S.base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));
    if (S.base == NULL)
        return false;
    S.top = S.base;
    S.stack_size = STACK_INIT_SIZE;
    return true;
}

// 销毁
bool DestoryStack(SqStack &S)
{
    if (!S.base)
        return false;
    free(S.base);
    S.base = S.top = NULL;
    S.stack_size = 0;
    return true;
}

// 清空
bool ClearStack(SqStack &S)
{
    if (!S.base)
        return false;
    S.top = S.base;
    return true;
}

// 判空
bool StackEmpty(SqStack S)
{
    return S.top == S.base;
}

// 长度
int StackLength(SqStack S)
{
    return S.top - S.base;
}

// 获取栈顶元素
bool GetTop(SqStack S, int &e)
{
    if (S.top == S.base)
        return false;
    e = *(S.top - 1);
    return true;
}

// 压栈
bool Push(SqStack &S, int e)
{
    if (StackLength(S) >= S.stack_size)
    {
        S.base = (int *)realloc(S.base, (S.stack_size + STACKINCREMENT) * sizeof(int));
        if (!S.base)
            return false;
        S.top = S.base + S.stack_size;
        S.stack_size += STACKINCREMENT;
    }
    *S.top++ = e;
    return true;
}

// 出栈
bool Pop(SqStack &S, int &e)
{
    if (S.top == S.base)
        return false;
    e = *--S.top;
    return true;
}

// 打印
void Print(SqStack S)
{
    printf("\n-----栈顶-----\n");
    for (int i = StackLength(S); i < S.stack_size; i++)
    {
        printf("--\n");
    }
    for (int i = 1; i < StackLength(S) + 1; i++)
    {
        printf("%d\n", *(S.top - i));
    }
    printf("-----栈底-----\n\n");
}

int main()
{
    // 初始化
    SqStack S;
    InitStack(S);

    // 压栈
    Push(S, 3);
    Push(S, 65);
    Push(S, 9);
    Push(S, 29);
    Push(S, 37);
    Print(S);

    // 判空
    bool isEmpty = StackEmpty(S);
    printf("栈是否为空: %d\n", isEmpty);

    // 长度
    int length = StackLength(S);
    printf("栈长度为: %d\n", length);

    int e;
    GetTop(S, e);
    printf("栈顶元素为%d \n", e);

    Pop(S, e);
    printf("栈顶元素%d 出栈\n", e);
    Print(S);
    DestoryStack(S);
    return 0;
}